package cn.thornbird.orgsync.config;

import cn.thornbird.orgsync.annotation.CurrentUser;
import cn.thornbird.orgsync.model.UserData;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.http.CacheControl;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.ContentVersionStrategy;
import org.springframework.web.servlet.resource.VersionResourceResolver;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new CurrentUserArgumentResolver());
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/swagger-ui/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
        registry.addResourceHandler("/public/**").addResourceLocations("file:./public/");
        registry.addResourceHandler("/**").addResourceLocations("classpath:/",
                "classpath:/static/", "classpath:/templates/");

        VersionResourceResolver versionResourceResolver = new VersionResourceResolver().addVersionStrategy(
                new ContentVersionStrategy(), "/**");
        CacheControl cacheControl = CacheControl.maxAge(30, TimeUnit.DAYS).cachePublic();
        registry.addResourceHandler("/libs/**/*.css", "/libs/**/*.js")
                .addResourceLocations("classpath:/static/libs/")
                .setCacheControl(cacheControl).resourceChain(true).addResolver(versionResourceResolver);
        registry.addResourceHandler("/index/static/**/*.css", "/index/static/**/*.js")
                .addResourceLocations("classpath:/templates/index/static/")
                .setCacheControl(cacheControl).resourceChain(true).addResolver(versionResourceResolver);
        registry.addResourceHandler("/images/*.png", "/images/*.jpg", "/images/*.jpeg")
                .addResourceLocations("classpath:/static/images/")
                .setCacheControl(cacheControl).resourceChain(true).addResolver(versionResourceResolver);
        registry.addResourceHandler("*.json", "/*.ico", "/*.png", "/*.txt", "/*.pdf")
                .addResourceLocations("classpath:/static/")
                .setCacheControl(cacheControl).resourceChain(true).addResolver(versionResourceResolver);
    }


    static class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver {

        @Override
        public boolean supportsParameter(MethodParameter parameter) {
            return parameter.getParameterType().isAssignableFrom(UserData.class) &&
                    parameter.hasParameterAnnotation(CurrentUser.class);
        }

        @Override
        public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                      NativeWebRequest webRequest, WebDataBinderFactory binderFactory)
                throws Exception {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            return authentication.getPrincipal();
        }

    }

}
